/**
 *@ProjectName  StudentScoreManagement
 *@Version      6.0_array
 *@Author       李一凡
 *@Date         2018/4/23
 *@Description  用结构数组实现对学生数据的组织
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NUMBER 30
#define MAX_NAME_LENGTH 20
#define true 1
#define false 0
#define boolean int

enum
{
    Excellent = 0,Well = 1,Medium = 2,Pass = 3,Fail = 4
};

enum
{
    Subject_1 = 0,Subject_2 = 1,Subject_3 = 2,Subject_4 = 3,Subject_5 = 4,Subject_6 = 5
};
/*
    定义学生结构
*/
typedef struct student
{
    int id;
    char name[MAX_NAME_LENGTH];
    double score[6];
    double total;
    double average;
} Student;

Student StudentArray[MAX_NUMBER];
int NumberOfStudents;
int NumberOfSubjects;

void FirstPage();
void Input(Student[],int);       //创建链表并向链表中录入信息
void CaclEverySubject();        //计算每门科目的总分和平均分
void CaclEveryStudent();        //计算每个学生的总分和平均分
void Sort(int,boolean (*p)(double a,double b));
boolean Ascending(double,double);
boolean Descending(double,double);
void SortByName();
int SearchByNumber(int);        //如果找到，返回该学生索引，否则返回-1
int SearchByName(char[MAX_NAME_LENGTH]);
void Statistics();
void List();
void WriteInFile();
void ReadFromFile();

int main()
{
    while(true)
    {
        FirstPage();
    }
    return 0;
}

void FirstPage()
{
    printf("1.Input record\n");
    printf("2.Calculate total and average score of every course\n");
    printf("3.Calculate total and average score of every student\n");
    printf("4.Sort in descending order by total score of every student\n");
    printf("5.Sort in ascending order by total score of every student\n");
    printf("6.Sort in ascending order by number\n");
    printf("7.Sort in ascending order by name\n");
    printf("8.Search by number\n");
    printf("9.Search by name\n");
    printf("10.Statistic analysis for every course\n");
    printf("11.List record\n");
    printf("12.Write to a file\n");
    printf("13.Read from a file\n");
    printf("0.exit\n");
    printf("Please enter your choice\n");

    int choice;
    scanf("%d",&choice);
    switch(choice)
    {
    case 1:
        system("cls");
        printf("请输入要录入的学生人数（小于30）:\n");
        scanf("%d",&NumberOfStudents);
        printf("请输入要录入的课程的门数（小于6）:\n");
        scanf("%d",&NumberOfSubjects);
        int i = 0;
        for(i = 0; i < NumberOfStudents; i++)
        {
            Input(StudentArray,i);
        }
        CaclEveryStudent();
        break;
    case 2:
        system("cls");
        CaclEverySubject();
        break;
    case 3:
        system("cls");
        List();
        //成绩表输出
        break;
    case 4:
        system("cls");
        Sort(0,Descending);
        for(i = 0; i < NumberOfStudents; i++)
        {
            printf("姓名:%s\t总分:%.2lf\n",StudentArray[i].name,StudentArray[i].total);
        }
        break;
    case 5:
        system("cls");
        Sort(0,Ascending);
        for(i = 0; i < NumberOfStudents; i++)
        {
            printf("姓名:%s\t总分:%.2lf\n",StudentArray[i].name,StudentArray[i].total);
        }
        break;
    case 6:
        system("cls");
        Sort(1,Ascending);
        for(i = 0; i < NumberOfStudents; i++)
        {
            printf("姓名:%s\t学号:%d\t总分:%.2lf\n",StudentArray[i].name,StudentArray[i].id,StudentArray[i].total);
        }
        break;
    case 7:
        system("cls");
        SortByName();
        for(i = 0; i < NumberOfStudents; i++)
        {
            printf("姓名:%s\t学号:%d\t总分:%.2lf\n",StudentArray[i].name,StudentArray[i].id,StudentArray[i].total);
        }
        break;
    case 8:
        system("cls");
        int IdToSearch;
        printf("请输入要查找的学号:\n");
        scanf("%d",&IdToSearch);
        int result_byNmuber = SearchByNumber(IdToSearch);
        if(result_byNmuber == -1)
        {
            printf("没有找到该学生信息\n");
        }
        else
        {
            printf("姓名:%s\t总分:%.2lf\n",StudentArray[result_byNmuber].name,StudentArray[result_byNmuber].total);
        }
        break;
    case 9:
        system("cls");
        char NameToSearch[MAX_NAME_LENGTH];
        printf("请输入要查找的名字:\n");
        scanf("%s",NameToSearch);
        int result_byName = SearchByName(NameToSearch);
        if(result_byName == -1)
        {
            printf("没有找到该学生信息\n");
        }
        else
        {
            printf("姓名:%s\t总分:%.2lf\n",StudentArray[result_byName].name,StudentArray[result_byName].total);
        }
        break;
    case 10:
        system("cls");
        Statistics();
        break;
    case 11:
        system("cls");
        List();
        break;
    case 12:
        system("cls");
        WriteInFile();
        break;
    case 13:
        system("cls");
        ReadFromFile();
        CaclEveryStudent();
        CaclEverySubject();
        break;
    case 0:
        exit(0);
        break;
    default:
        printf("输入错误，请重新输入！\n");
        break;

    }
}

void Input(Student StudentArray[MAX_NUMBER],int InsertIndex)
{
    int i = 0;
    int j = 0;
    int k = NumberOfSubjects;
    tag:printf("请输入学生的学号:\n");
    int idToInput;
    scanf("%d",&idToInput);
    for(j = 0;j < InsertIndex;j++)
    {
        if(idToInput == StudentArray[j].id)
        {
            printf("请重新输入学号!\n");
            goto tag;
        }
    }
    StudentArray[InsertIndex].id = idToInput;
    printf("请输入学生的姓名:\n");
    fflush(stdin);
    scanf("%s",StudentArray[InsertIndex].name);
    fflush(stdin);
    for(i = 0 ; i < NumberOfSubjects; i++)
    {
        printf("请输入第%d门科目的成绩\n",(i + 1));
        scanf("%lf",&StudentArray[InsertIndex].score[i]);
    }
    for(k = NumberOfSubjects;k < 6;k++)
    {
        StudentArray[InsertIndex].score[k] = 0;
    }
    printf("输入成功!\n");
    system("cls");
}

void CaclEverySubject()
{
    if(StudentArray[0].id == 0)
    {
        printf("请先使用Input功能");
        return;
    }
    int i;
    double EverySubjectTotal[6] = {0.0};
    for(i = 0; i < NumberOfStudents; i++)
    {
        EverySubjectTotal[Subject_1] += StudentArray[i].score[Subject_1];
        EverySubjectTotal[Subject_2] += StudentArray[i].score[Subject_2];
        EverySubjectTotal[Subject_3] += StudentArray[i].score[Subject_3];
        EverySubjectTotal[Subject_4] += StudentArray[i].score[Subject_4];
        EverySubjectTotal[Subject_5] += StudentArray[i].score[Subject_5];
        EverySubjectTotal[Subject_6] += StudentArray[i].score[Subject_6];
    }
    for(i = 0;i < NumberOfSubjects;i++)
    {
        printf("科目%d总分为:%.2lf,平均分为:%.2lf\n",i + 1,EverySubjectTotal[i],EverySubjectTotal[i] / NumberOfStudents);
    }
    /*
    printf("科目%d总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_1],EverySubjectTotal[Subject_1] / NumberOfStudents);
    printf("科目%d总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_2],EverySubjectTotal[Subject_2] / NumberOfStudents);
    printf("科目三总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_3],EverySubjectTotal[Subject_3] / NumberOfStudents);
    printf("科目四总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_4],EverySubjectTotal[Subject_4] / NumberOfStudents);
    printf("科目五总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_5],EverySubjectTotal[Subject_5] / NumberOfStudents);
    printf("科目六总分为:%.2lf,平均分为:%.2lf\n",EverySubjectTotal[Subject_6],EverySubjectTotal[Subject_6] / NumberOfStudents);
    */
}

void CaclEveryStudent()
{
    int i,j;
    for(i = 0; i < NumberOfStudents; i++)
    {
        StudentArray[i].total = 0;
        StudentArray[i].average = 0;
        for(j = 0; j < 6; j++)
        {
            StudentArray[i].total += StudentArray[i].score[j];
        }
        StudentArray[i].average = StudentArray[i].total / NumberOfSubjects;
    }
}

boolean Ascending(double a,double b)
{
    return a > b;
}

boolean Descending(double a,double b)
{
    return a < b;
}

void Sort(int tag,boolean (*p)(double a,double b))
{
    int i,j;
    int SearchTag = 0;
    int SearchIndex = 0;
    if(tag == 0)
    {
        //按总分排序
        for(i = 0; i < NumberOfStudents; i++)
        {
            SearchTag = StudentArray[i].total;
            SearchIndex = i;
            for(j = i; j < NumberOfStudents; j++)
            {
                if((*p)(SearchTag,StudentArray[j].total))
                {
                    SearchIndex = j;
                    SearchTag = StudentArray[j].total;
                }
            }
            Student temp = StudentArray[i];
            StudentArray[i] = StudentArray[SearchIndex];
            StudentArray[SearchIndex] = temp;
        }
        return;
    }
    if(tag == 1)
    {
        //按学号排序
        for(i = 0; i < NumberOfStudents; i++)
        {
            SearchTag = StudentArray[i].id;
            SearchIndex = i;
            for(j = i; j < NumberOfStudents; j++)
            {
                if((*p)(SearchTag,StudentArray[j].id))
                {
                    SearchIndex = j;
                    SearchTag = StudentArray[j].id;
                }
            }
            Student temp = StudentArray[i];
            StudentArray[i] = StudentArray[SearchIndex];
            StudentArray[SearchIndex] = temp;
        }
        return;
    }

}

void SortByName()
{
    int i,j;
    for(i = 0;i < NumberOfStudents;i++)
    {
        for(j = i;j < NumberOfStudents - 1;j++)
        {
            if(strcmp(StudentArray[j].name,StudentArray[j + 1].name) > 0)
            {
                Student temp = StudentArray[j];
                StudentArray[j] = StudentArray[j + 1];
                StudentArray[j + 1] = temp;
            }
        }
    }
}

int SearchByNumber(int SearchId)
{
    int i;
    for(i = 0;i < NumberOfStudents;i++)
    {
        if(StudentArray[i].id == SearchId)
        {
            return i;
        }
    }
    return -1;
}

int SearchByName(char NameToSearch[MAX_NAME_LENGTH])
{
    int i;
    for(i = 0;i < NumberOfStudents;i++)
    {
        if(strcmp(StudentArray[i].name,NameToSearch) == 0)
        {
            return i;
        }
    }
    return -1;
}

void Statistics()
{
    int StatisticsArray[6][5] = {{0},{0},{0},{0},{0},{0}};            //此二维数组的6行表示6门科目，5列代表五种状态。
    int i,j;
    for(i = 0;i < NumberOfStudents;i++)
    {
        for(j = 0;j < 6;j++)
        {
            if(StudentArray[i].score[j] >= 90 && StudentArray[i].score[j] <= 100)
                StatisticsArray[j][Excellent]++;
            else if(StudentArray[i].score[j] >= 80 && StudentArray[i].score[j] < 90)
                StatisticsArray[j][Well]++;
            else if(StudentArray[i].score[j] >= 70 && StudentArray[i].score[j] < 80)
                StatisticsArray[j][Medium]++;
            else if(StudentArray[i].score[j] >= 60 && StudentArray[i].score[j] < 70)
                StatisticsArray[j][Pass]++;
            else
                StatisticsArray[j][Fail]++;
        }
    }
    for(i = 0;i < NumberOfSubjects;i++)
    {
        printf("科目%d优秀人数：%d, 占比：%.2lf\n",i + 1,StatisticsArray[i][Excellent],((double)StatisticsArray[i][Excellent]) / NumberOfStudents) ;
        printf("科目%d良好人数：%d, 占比：%.2lf\n",i + 1,StatisticsArray[i][Well],((double)StatisticsArray[i][Well]) / NumberOfStudents);
        printf("科目%d中等人数：%d, 占比：%.2lf\n",i + 1,StatisticsArray[i][Medium],((double)StatisticsArray[i][Medium]) / NumberOfStudents);
        printf("科目%d通过人数：%d, 占比：%.2lf\n",i + 1,StatisticsArray[i][Pass],((double)StatisticsArray[i][Pass]) / NumberOfStudents);
        printf("科目%d不及格人数：%d, 占比：%.2lf\n",i + 1,StatisticsArray[i][Fail],((double)StatisticsArray[i][Fail]) / NumberOfStudents);
    }
    /*
    printf("科目一优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_1][Excellent],((double)StatisticsArray[Subject_1][Excellent]) / NumberOfStudents) ;
    printf("科目一良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_1][Well],((double)StatisticsArray[Subject_1][Well]) / NumberOfStudents);
    printf("科目一中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_1][Medium],((double)StatisticsArray[Subject_1][Medium]) / NumberOfStudents);
    printf("科目一通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_1][Pass],((double)StatisticsArray[Subject_1][Pass]) / NumberOfStudents);
    printf("科目一不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_1][Fail],((double)StatisticsArray[Subject_1][Fail]) / NumberOfStudents);

    printf("科目二优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_2][Excellent],((double)StatisticsArray[Subject_2][Excellent]) / NumberOfStudents) ;
    printf("科目二良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_2][Well],((double)StatisticsArray[Subject_2][Well]) / NumberOfStudents);
    printf("科目二中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_2][Medium],((double)StatisticsArray[Subject_2][Medium]) / NumberOfStudents);
    printf("科目二通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_2][Pass],((double)StatisticsArray[Subject_2][Pass]) / NumberOfStudents);
    printf("科目二不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_2][Fail],((double)StatisticsArray[Subject_2][Fail]) / NumberOfStudents);

    printf("科目三优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_3][Excellent],((double)StatisticsArray[Subject_3][Excellent]) / NumberOfStudents) ;
    printf("科目三良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_3][Well],((double)StatisticsArray[Subject_3][Well]) / NumberOfStudents);
    printf("科目三中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_3][Medium],((double)StatisticsArray[Subject_3][Medium]) / NumberOfStudents);
    printf("科目三通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_3][Pass],((double)StatisticsArray[Subject_3][Pass]) / NumberOfStudents);
    printf("科目三不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_3][Fail],((double)StatisticsArray[Subject_3][Fail]) / NumberOfStudents);

    printf("科目四优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_4][Excellent],((double)StatisticsArray[Subject_4][Excellent]) / NumberOfStudents) ;
    printf("科目四良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_4][Well],((double)StatisticsArray[Subject_4][Well]) / NumberOfStudents);
    printf("科目四中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_4][Medium],((double)StatisticsArray[Subject_4][Medium]) / NumberOfStudents);
    printf("科目四通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_4][Pass],((double)StatisticsArray[Subject_4][Pass]) / NumberOfStudents);
    printf("科目四不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_4][Fail],((double)StatisticsArray[Subject_4][Fail]) / NumberOfStudents);

    printf("科目五优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_5][Excellent],((double)StatisticsArray[Subject_5][Excellent]) / NumberOfStudents) ;
    printf("科目五良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_5][Well],((double)StatisticsArray[Subject_5][Well]) / NumberOfStudents);
    printf("科目五中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_5][Medium],((double)StatisticsArray[Subject_5][Medium]) / NumberOfStudents);
    printf("科目五通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_5][Pass],((double)StatisticsArray[Subject_5][Pass]) / NumberOfStudents);
    printf("科目五不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_5][Fail],((double)StatisticsArray[Subject_5][Fail]) / NumberOfStudents);

    printf("科目六优秀人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_6][Excellent],((double)StatisticsArray[Subject_6][Excellent]) / NumberOfStudents) ;
    printf("科目六良好人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_6][Well],((double)StatisticsArray[Subject_6][Well]) / NumberOfStudents);
    printf("科目六中等人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_6][Medium],((double)StatisticsArray[Subject_6][Medium]) / NumberOfStudents);
    printf("科目六通过人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_6][Pass],((double)StatisticsArray[Subject_6][Pass]) / NumberOfStudents);
    printf("科目六不及格人数：%d, 占比：%.2lf\n",StatisticsArray[Subject_6][Fail],((double)StatisticsArray[Subject_6][Fail]) / NumberOfStudents);
    */
}

void List()
{
    int i,j;
    for(i = 0;i < NumberOfStudents;i++)
    {
        printf("学号：%d\t姓名：%s\t总分：%.2lf\t平均分：%.2lf\t",
                    StudentArray[i].id,StudentArray[i].name,StudentArray[i].total,StudentArray[i].average);
        for(j = 0;j < NumberOfSubjects;j++)
        {
            printf("科目%d成绩：%.2lf\t",j + 1,StudentArray[i].score[j]);
            printf("\n");
        }
    }
}

void WriteInFile()
{
    system("cls");
    printf("请输入保存位置：\n");
    char src[500];
    scanf("%s",src);
    FILE *file = fopen(src,"w");
    if(file == NULL)
    {
        printf("文件打开失败!\n");
        return;
    }
    int i;
    for(i = 0;i < NumberOfStudents;i++)
    {
        fprintf(file,"%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t%.2lf\n",StudentArray[i].id,StudentArray[i].name,StudentArray[i].total,StudentArray[i].average,
                StudentArray[i].score[Subject_1],StudentArray[i].score[Subject_2],StudentArray[i].score[Subject_3],StudentArray[i].score[Subject_4],StudentArray[i].score[Subject_5],StudentArray[i].score[Subject_6]);
    }
    printf("文件写入成功!\n");
    fclose(file);
    return;
}
void ReadFromFile()
{
    printf("请输入读取文件的位置：\n");
    char src[500];
    scanf("%s",src);
    FILE *file = fopen(src,"r");
    printf("请输入课程门数:\n");
    scanf("%d",&NumberOfSubjects);
    if(file == NULL)
    {
        printf("文件打开失败!\n");
        return ;
    }
    //先清除当前数组中的内容
    int i,j;
    for(i = 0;i < NumberOfStudents;i++)
    {
        strcpy(StudentArray[i].name,"");
        StudentArray[i].id = 0;
        StudentArray[i].total = 0;
        StudentArray[i].average = 0;
        for(j = 0;j < 6;j++)
        {
            StudentArray[i].score[j] = 0;
        }
    }
    NumberOfStudents = 0;
    i = 0;
    while(!feof(file))
    {
        fscanf(file,"%d\t%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",&StudentArray[i].id,StudentArray[i].name,&StudentArray[i].total,&StudentArray[i].average,
                &StudentArray[i].score[Subject_1],&StudentArray[i].score[Subject_2],&StudentArray[i].score[Subject_3],&StudentArray[i].score[Subject_4],&StudentArray[i].score[Subject_5],&StudentArray[i].score[Subject_6]);
        i++;
        NumberOfStudents++;
    }
    printf("文件读取成功!\n");
    return ;
}
